#include "QtLightControlPanel.h"
#include "qwidget.h"
#include "QListView"
#include "QVBoxLayout"
#include "QAbstractItemModel"
#include "LightPresetDelegate.h"
#include "LightPresetData.h"
#include "LightsetPainter.h"
#include "LightPresetPlaybar.h"
#include "modelViewRules.h"
#include "ActionListController.h"


/** @class QtLightControlPanel
 * implementation of ::IF_GuiLightControlPanel interface that uses Qt widgets.
 * Items are displayed in a list view with activation controller, (see ::ActionListView).
 */

#define CONTROL_BAR_MIN_HEIGHT     50

/* GUI controls are generated outside factory */

QtLightControlPanel::QtLightControlPanel(int numberOfChannels, ActionListController &actionController,
                                          QAbstractItemModel *model, QWidget *parent) :
   IF_GuiLightControlPanel(parent),
   m_actionController(actionController)
{
   m_presetModel = model;

   m_presetsView = new ActionListView( actionController, new LightsetPainter(), this);
   m_presetsView->setModel( model);

   QHBoxLayout *layout = new QHBoxLayout( this);
   setLayout( layout );
   layout->setMargin( 2);
   layout->addWidget( m_presetsView);

   m_presetsView->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding);

   m_delegate = new LightPresetDelegate( numberOfChannels, this);
   m_presetsView->setItemDelegate( m_delegate );

   m_controlBar = new LightPresetPlaybar( m_presetsView);
   m_controlBar->setMinimumHeight( CONTROL_BAR_MIN_HEIGHT );
   m_controlBar->setVisible( false);

   m_presetsView->setActionBar( m_controlBar);

   connect( m_controlBar, SIGNAL(play()), this, SLOT(onPlayRequest()) );
   connect( m_controlBar, SIGNAL(edit()), this, SLOT(onEditRequest()) );
   connect( m_controlBar, SIGNAL(remove()), m_presetsView, SLOT(deleteActiveItem()) );

   connect( &m_actionController, SIGNAL(activeRowChanged(int)),
            this, SLOT(onActiveChanged(int)) );

   /* when model change, control bar must also be updated */
   connect( m_presetModel, SIGNAL(layoutChanged()),
            this, SLOT(updateControlBar()) );
}

/**
 * @brief callback when GUI request to activate preset.
 */
void QtLightControlPanel::onPlayRequest()
{
   Q_ASSERT(m_presetModel != NULL);

   try
   {
      const LightPresetData *preset;
      int activeRow = m_actionController.activeItemRow();
      preset = m_presetModel->index(activeRow, 0).data(modelViewRules::Binary).value<const LightPresetData *>();

      if (preset != NULL)
      {
         QString activePresetLabel = preset->name();
         emit triggerTransitionRequest( activePresetLabel);
      }
   }
   catch (QString &)
   {
      Q_ASSERT(false);
   }
}

/**
 * @brief callback when GUI requests to edit the preset.
 */
void QtLightControlPanel::onEditRequest()
{
   int activeRow = m_actionController.activeItemRow();
   m_presetsView->edit( m_presetModel->index( activeRow, 0) );
}

void QtLightControlPanel::onActiveChanged(int  row)
{
   QModelIndex rowIndex = m_presetModel->index( row, 0);

   applyLevelsOfIndex( rowIndex);
}

/** update current light values to control bar */
void QtLightControlPanel::updateControlBar()
{
   QModelIndex rowIndex = m_presetModel->index( m_actionController.activeItemRow(), 0);
   applyLevelsOfIndex(rowIndex);
}

void QtLightControlPanel::applyLevelsOfIndex(const QModelIndex & rowIndex)
{
   if (rowIndex != QModelIndex())
   {
      const LightPresetData *preset;
      preset = rowIndex.data( modelViewRules::Binary).value<const LightPresetData *>();
      Q_ASSERT( preset != NULL );

      m_controlBar->show();
      m_controlBar->setValueList( preset->levelList());
   }
   else
   {
      m_controlBar->hide();
   }
}

void QtLightControlPanel::shiftFocusedUp()
{
   m_presetsView->shiftFocusedUp();
}

void QtLightControlPanel::shiftFocusedDown()
{
   m_presetsView->shiftFocusedDown();
}

void QtLightControlPanel::triggerActivePreset()
{
   onPlayRequest();
}
